﻿using System;
using System.Collections.Generic;
using System.Text;
using CookComputing.XmlRpc;

namespace CodeGecko.AntiSpam.BlogSpamNet {
    using CodeGecko.AntiSpam.BlogSpamNet.Interfaces;
    using CodeGecko.AntiSpam.BlogSpamNet.Structs;
    public class BlogSpamNet {
        private Uri Url { get; set; }
        private static string _url = "http://test.blogspam.net:8888/";

        public BlogSpamNet() { Url = new Uri(_url); }
        public BlogSpamNet(string url) { Url = new Uri(url); }

        #region Akismet-compatible methods

        public void SubmitSpam(Comment comment) { ClassifyComment(comment.comment, true); }
        public void SubmitHam(Comment comment) { ClassifyComment(comment.comment, false); }
        public Boolean CommentCheck(Comment comment) { return TestComment(comment).Equals("OK"); }

        #endregion 

        public string TestComment(Comment comment) { return GetProxy().testComment(comment); }

        public string ClassifyComment(string comment, bool isSpam) {
            return GetProxy().classifyComment(new TrainComment() { comment = comment, train = (isSpam ? "spam" : "ok") });
        }
        
        public Stats GetStats(string siteUrl) { return GetProxy().getStats(siteUrl); }

        public string[] GetPlugins() { return GetProxy().getPlugins(); }

        #region Helpers

        internal IBlogSpam GetProxy() {
            IBlogSpam _proxy = (IBlogSpam)XmlRpcProxyGen.Create(typeof(IBlogSpam));
            XmlRpcClientProtocol _server = (XmlRpcClientProtocol)_proxy;
            _server.Url = Url.ToString();
            return _proxy;
        }

        #endregion
    }
}

namespace CodeGecko.AntiSpam.BlogSpamNet.Structs {
    #region XMLRPC structs
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct Comment {
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember]
        public string comment { get; set;}
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember]
        public string ip { get; set; }

        public string agent { get; set;}
        public string email	{ get; set; }
        public string link { get; set; }
        public string name { get; set; }
        public string options { get; set; }
        public string site { get; set; }
        public string subject { get; set; }
        public string version { get; set; }
    }

    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct TrainComment {
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember]
        public string comment { get; set;}
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember]
        public string train { get; set; }
    }

    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct Stats {
        public int ok { get; set; }
        public int spam { get; set; }
    }
    #endregion

    public class CommentOptions {
        public CommentOptions() { }
        public List<Uri> Blacklist { get; set; }
        public List<Uri> Whitelist { get; set; }
        public List<string> Plugins { get; set; }
        public List<string> MandatoryFields { get; set; }
        public bool TestSpam { get; set; }

    }
}

namespace CodeGecko.AntiSpam.BlogSpamNet.Interfaces {
    using CodeGecko.AntiSpam.BlogSpamNet.Structs;
    public interface IBlogSpam {
        [XmlRpcMethod("testComment")]
        string testComment(Comment comment);

        [XmlRpcMethod("classifyComment")]
        string classifyComment(TrainComment commentToTrain);

        [XmlRpcMethod("getStats")]
        Stats getStats(string siteUrl);

        [XmlRpcMethod("getPlugins")]
        string[] getPlugins();
    }
}